﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Drawing.Design;
using System.ComponentModel;
using System.Windows.Forms.Design;
using System.Windows.Forms.Integration;

namespace comm.editor
{
    public class ItemCateChooseEditor : UITypeEditor
    {
        public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context)
        {
            return UITypeEditorEditStyle.DropDown;
        }
        public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value)
        {
            var edSvc = (IWindowsFormsEditorService)provider.GetService(typeof(IWindowsFormsEditorService));
            if (edSvc != null)
            {
                var cateDic = DefineFile.LastInstance.GetAllItemCate();
                var nodeDic = new Dictionary<string, objst.ILinearTreeNode>();
                foreach (var key in cateDic.Keys)
                {
                    nodeDic.Add(key, cateDic[key]);
                }
                var uc = new UCLinearTree(nodeDic) { SelNode = value.ToString() };
                var elHost = new ElementHost
                {
                    Width = 480,
                    Height = 360,
                    Child = uc
                };
                edSvc.DropDownControl(elHost);
                return uc.SelNode;
            }
            return value;
        }
    }

    /// <summary>
    /// UCLinearTree.xaml 的交互逻辑
    /// </summary>
    public partial class UCLinearTree : UserControl
    {
        string _selNode = "";
        public string SelNode
        {
            get { return _selNode; }
            set
            {
                _selNode = value; Fill();
            }
        }

        Dictionary<string, objst.ILinearTreeNode> _nodeDic = null;
        TreeNode _root = null;
        bool _editMode = false;

        public UCLinearTree(Dictionary<string, objst.ILinearTreeNode> nodeDic, bool editMode = false)
        {
            InitializeComponent();

            _nodeDic = nodeDic;
            _editMode = editMode;

            _root = new TreeNode(comm.GUID.NewString(), "");
            _root.Children.AddRange(TreeNode.Create(_nodeDic));

            #region contextMenu
            var contextMenu = new ContextMenu { FontSize = 14 };
            TextOptions.SetTextFormattingMode(contextMenu, TextFormattingMode.Display);

            if (_editMode)
            {
                var mAddRoot = new MenuItem { Header = new TextBlock { Text = "New Root" } };
                mAddRoot.Click += new RoutedEventHandler((o, e) =>
                {
                    _root.Children.Add(new TreeNode(comm.GUID.NewString(), "NewNode"));
                    Fill();
                });
                contextMenu.Items.Add(mAddRoot);
            }

            var mToJson = new MenuItem { Header = new TextBlock { Text = "Edit(Json)" } };
            mToJson.Click += new RoutedEventHandler((o, e) =>
            {
                tbJson.Text = comm.JsonSerializer.Serialize(_root.ToNodeDic(true), false);
                gridJson.Visibility = Visibility.Visible;
            });
            contextMenu.Items.Add(mToJson);

            ContextMenu = contextMenu;
            #endregion

            if (_editMode)
            {
                btnToTree.Visibility = Visibility.Visible;
                btnToTree.Click += new RoutedEventHandler(btnToTree_Click);
            }

            Fill();

            treeView.SelectedItemChanged += new RoutedPropertyChangedEventHandler<object>(treeView_SelectedItemChanged);
            btnClose.Click += new RoutedEventHandler(btnClose_Click);
        }

        void btnToTree_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                var dic = comm.JsonSerializer.Deserialize<Dictionary<string, comm.objst.LinearTreeNode>>(tbJson.Text);
                var nodeDic = new Dictionary<string, objst.ILinearTreeNode>();
                foreach (var key in dic.Keys)
                {
                    nodeDic.Add(key, dic[key]);
                }
                _root.Children.Clear();
                _root.Children.AddRange(TreeNode.Create(nodeDic));
                gridJson.Visibility = Visibility.Collapsed;
                Fill();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }
        void btnClose_Click(object sender, RoutedEventArgs e)
        {
            gridJson.Visibility = Visibility.Collapsed;
        }
        void treeView_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
        {
            var tvi = (TreeViewItem)treeView.SelectedItem;
            _selNode = tvi.Tag.ToString();
        }
        void mDel_Click(object sender, RoutedEventArgs e)
        {
            var mi = (MenuItem)sender;
            var node = _root.Find(mi.Tag.ToString());
            node.Parent.Remove(node.Key);
            Fill();
        }

        void Fill()
        {
            treeView.Items.Clear();
            FillChildren(_root.Children, treeView);
        }
        void FillChildren(comm.TreeNodeCollection nodeLiet, ItemsControl tvi)
        {
            foreach (var item in nodeLiet)
            {
                var item2 = item;
                var tvi2 = new TreeViewItem
                {
                    Tag = item.Key,
                    Header = new TextBlock { Text = item.Key },
                    IsExpanded = true
                };

                if (_selNode == item.Key)
                {
                    TextBlock.SetFontWeight(tvi2, FontWeights.Bold);
                    tvi2.IsSelected = true;
                }

                if (_editMode)
                {
                    var sp = new StackPanel { Height = 26, Orientation = Orientation.Horizontal };
                    sp.Children.Add(new TextBlock
                    {
                        Text = item.Key,
                        Width = 120,
                        Padding = new Thickness(0),
                        Margin = new Thickness(0, 0, 4, 0),
                        VerticalAlignment = VerticalAlignment.Center
                    });

                    #region tbName
                    var tbName = new TextBox
                    {
                        Text = item.Key + "," + item.Name,
                        Width = 180,
                        Margin = new Thickness(0, 0, 4, 0),
                        VerticalAlignment = VerticalAlignment.Center
                    };
                    tbName.TextChanged += new TextChangedEventHandler((o, e) =>
                    {
                        var ss = tbName.Text.Trim().Split(',');
                        if (ss.Length == 2)
                        {
                            item2.Name = ss[1];
                            if (ss[0] != item2.Key)
                            {
                                if (_root.Find(ss[0]) == null)
                                {
                                    item2.Parent.Remove(item2.Key);
                                    item2.Key = ss[0];
                                    item2.Parent.Children.Add(item2);
                                    tbName.Opacity = 1;
                                }
                                else
                                {
                                    tbName.Opacity = .7;
                                }
                            }
                        }
                        else
                        {
                            tbName.Opacity = .7;
                        }
                    });
                    sp.Children.Add(tbName);
                    #endregion

                    #region btnAdd
                    var btnAdd = new Button
                    {
                        Content = "+",
                        Width = 22,
                        Height = 22,
                        Margin = new Thickness(0, 0, 4, 0),
                        VerticalAlignment = VerticalAlignment.Center
                    };
                    btnAdd.Click += new RoutedEventHandler((o, e) =>
                    {
                        item2.Children.Add(new TreeNode(comm.GUID.NewString(), ""));
                        Fill();
                    });
                    sp.Children.Add(btnAdd);
                    #endregion

                    #region btnDel
                    var btnDel = new Button
                    {
                        Content = "X",
                        Width = 22,
                        Height = 22,
                        Margin = new Thickness(0, 0, 4, 0),
                        VerticalAlignment = VerticalAlignment.Center
                    };
                    btnDel.Click += new RoutedEventHandler((o, e) =>
                    {
                        item2.Parent.Remove(item2.Key);
                        Fill();
                    });
                    sp.Children.Add(btnDel);
                    #endregion

                    tvi2.Header = sp;
                }

                tvi.Items.Add(tvi2);
                FillChildren(item.Children, tvi2);
            }
        }

        public Dictionary<string, objst.LinearTreeNode> ToNodeDic()
        {
            return _root.ToNodeDic(true);
        }
    }
}
